/*
 * Created on Mar 7, 2005
 */
package org.scohen.juploadr.uploadapi.zooomr.ui;

import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.scohen.juploadr.prefs.BaseConfigurationForm;
import org.scohen.juploadr.prefs.Fault;
import org.scohen.juploadr.ui.MessageUtils;
import org.scohen.juploadr.uploadapi.Account;
import org.scohen.juploadr.uploadapi.CommunicationException;
import org.scohen.juploadr.uploadapi.ImageUploadApi;
import org.scohen.juploadr.uploadapi.ProtocolException;
import org.scohen.juploadr.uploadapi.zooomr.Messages;
import org.scohen.juploadr.uploadapi.zooomr.ZooomrRestApi;
import org.scohen.juploadr.uploadapi.zooomr.authentication.ZooomrAccount;
import org.scohen.juploadr.util.ConversionUtils;

public class ZoomrAccountForm extends BaseConfigurationForm {
    private static final DecimalFormat percentFormat = new DecimalFormat("####0.##%"); //$NON-NLS-1$

    private Label accountTypeLabel;
    private Label accountType;
    private Label downloadLimitLabel;
    private Label downloadLimit;
    private Label authorizeLabel;
    private Button authorize;
    private Label accountsLabel;
    private Combo accounts;
    private Button addAnotherAccount;
    private Button deleteAccount;
    private Label addAnotherAccountLabel;

    public ZoomrAccountForm(Composite parent) {
        super(parent);
    }

    /**
     * 
     */
    protected void initUI() {
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.horizontalSpacing = 5;
        this.setLayout(layout);
        if (api.isCurrentAccountAuthenticated()) {
            initAuthorizedComponents();
        }
        authorizeLabel = new Label(this, SWT.NONE);
        authorizeLabel.setText(""); //$NON-NLS-1$
        authorize = new Button(this, SWT.PUSH);
        authorize.setImage(api.getIcon());
        if (!api.isCurrentAccountAuthenticated()) {
            authorize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.CENTER));
        }
        authorize.setText(Messages.getString("juploadr.ui.button.validate.settings")); //$NON-NLS-1$
        authorize.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ZoomrAccountForm.this.checkPassword();
			}
		});

        addAnotherAccountLabel = new Label(this, SWT.NONE);
        addAnotherAccountLabel.setText(""); //$NON-NLS-1$

        addAnotherAccount = new Button(this, SWT.PUSH);
        addAnotherAccount.setText(org.scohen.juploadr.uploadapi.zooomr.Messages
                .getString("juploadr.ui.zooomr.accountform.addanother")); //$NON-NLS-1$
        addAnotherAccount.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ZooomrAccount account = (ZooomrAccount) api.newAccount("--"); //$NON-NLS-1$
				ZoomrAccountForm.this.authorizeAccount(account, true);
			}
		});
        addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent event) {
                ZoomrAccountForm.this.disposed(event);
            }
        });
    }

    /**
     * 
     */
    private void initAuthorizedComponents() {
        ZooomrAccount currentAccount = (ZooomrAccount) api.getCurrentAccount();
        accountsLabel = new Label(this, SWT.NONE);
        accountsLabel.setText(Messages.getString("juploadr.ui.label.username")); //$NON-NLS-1$

        Composite accountComp = new Composite(this, SWT.NONE);
        GridLayout layout = new GridLayout(2, false);

        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        accountComp.setLayoutData(data);
        accountComp.setLayout(layout);

        accounts = new Combo(accountComp, SWT.DROP_DOWN | SWT.READ_ONLY);

        accounts.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        Iterator iter = ZooomrAccount.allAccounts().values().iterator();
        int i = 0;
        while (iter.hasNext()) {
            Account account = (Account) iter.next();
            accounts.add(account.getName());
            if (account.equals(currentAccount)) {
                accounts.select(i);
            }
            i++;
        }

        accounts.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                if (event.doit) {
                    Combo combo = (Combo) event.widget;

                    String accountName = combo.getItem(combo.getSelectionIndex());
                    ZooomrAccount account = (ZooomrAccount) ZooomrAccount.allAccounts().get(accountName);
                    ZoomrAccountForm.this.api.setCurrentAccount(account);
                    try {
                        api.authenticate(account);
                    } catch (ProtocolException e) {
                        // this shouldn't happen because the account should
                        // already be authenticated
                        e.printStackTrace();
                    } catch (CommunicationException e) {
                        MessageUtils.showErrorMessage(Messages.getString("juploadr.ui.dialog.error.communication") //$NON-NLS-1$
                                + e.getMessage());
                    }
                    accountChanged(account);
                }
            }
        });

        deleteAccount = new Button(accountComp, SWT.PUSH);
        deleteAccount.setText("Delete");
        deleteAccount.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
                String accountName = accounts.getItems()[accounts.getSelectionIndex()];
                if (MessageUtils.showMessage("Are you sure you want to delete the account " + accountName + "@"
                        + ImageUploadApi.getInstance().getSiteName() + " and all of its preferences?",
                        "Confirm Delete", SWT.YES | SWT.NO)) {
                    Account account = (Account) ZooomrAccount.allAccounts().get(accountName);
                    account.delete();
                    List allAccounts = ZooomrRestApi.getInstance().allAccounts();
                    ZooomrAccount changedAccount = ZooomrAccount.getNullAccount();
                    if (allAccounts != null && allAccounts.size() > 0) {
                        changedAccount = (ZooomrAccount) allAccounts.get(0);
                    }
                    ZooomrRestApi.getInstance().setCurrentAccount(changedAccount);
                    ZoomrAccountForm.this.accountChanged(changedAccount);
                }
            }
		});
       
        accountTypeLabel = new Label(this, SWT.NONE);
        accountType = new Label(this, SWT.NONE);
        accountTypeLabel.setText(Messages.getString("juploadr.ui.label.accounttype")); //$NON-NLS-1$
        setAccountType(currentAccount);

        downloadLimitLabel = new Label(this, SWT.NONE);
        downloadLimit = new Label(this, SWT.NONE);
        downloadLimit.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        downloadLimitLabel.setText(Messages.getString("juploadr.ui.label.montly.limit")); //$NON-NLS-1$
        updateLimits();

    }

    /**
     * @param currentAccount
     */
    private void setAccountType(ZooomrAccount currentAccount) {
        accountType
                .setText(currentAccount.isPro() ? Messages.getString("juploadr.ui.account.pro") : Messages.getString("juploadr.ui.account.free")); //$NON-NLS-1$ //$NON-NLS-2$
    }

    /**
     * 
     */
    private void updateLimits() {
        Account currentAccount = api.getCurrentAccount();
        StringBuffer limitText = new StringBuffer();
        limitText.append(ConversionUtils.bytesToHumanReadable(currentAccount.getCurrentUploadUsed()));
        limitText.append("/"); //$NON-NLS-1$
        limitText.append(ConversionUtils.bytesToHumanReadable(currentAccount.getMonthlyUploadLimit()));
        limitText.append(" ("); //$NON-NLS-1$
        if (currentAccount.getMonthlyUploadLimit() > 0) {
            limitText.append(percentFormat.format(((double) currentAccount.getCurrentUploadUsed())
                    / ((double) currentAccount.getMonthlyUploadLimit())));
        } else {
            limitText.append(percentFormat.format(0));
        }
        limitText.append(")"); //$NON-NLS-1$
        downloadLimit.setText(limitText.toString());
    }

    public void saveChanges() {
    }

    public Fault validateChanges() {

        return null;
    }

    public String getFormName() {
        return Messages.getString("juploadr.ui.flickrform.title"); //$NON-NLS-1$
    }

    private void checkPassword() {
        Fault errors = validateChanges();
        if (errors != null) {
            MessageUtils.showErrorMessage(errors.getText());
        } else {
            boolean shouldRedraw = !api.isCurrentAccountAuthenticated();

            ZooomrAccount userInfo = (ZooomrAccount) api.getCurrentAccount();
            userInfo.setAuthenticated(false);
            authorizeAccount(userInfo, shouldRedraw);
        }
    }

    /**
     * @param account
     * @param shouldRedraw
     * @param flickrApi
     */
    private void authorizeAccount(ZooomrAccount account, boolean shouldRedraw) {
        try {
            account.setAuthenticated(false);
            api.authenticate(account);
            if (account.isAuthenticated()) {
                if (shouldRedraw) {
                    accountChanged(account);

                } else {
                    // they still aren't authenticated, and auth threw no
                    // exceptions. They cancelled.
                    // do nothing.

                }
                MessageUtils.showInfoMessage(Messages.getString("juploadr.ui.dialog.account.info.correct")); //$NON-NLS-1$
            }
        } catch (ProtocolException e) {
            MessageUtils.showErrorMessage(Messages.getString("juploadr.ui.dialog.error.invalid.credentials")); //$NON-NLS-1$
            api.setCurrentAccount(ZooomrAccount.getNullAccount());
        } catch (CommunicationException e) {
            MessageUtils.showErrorMessage(Messages.getString("juploadr.ui.dialog.error.communication") //$NON-NLS-1$
                    + e.getMessage());
        }

    }

    /**
     * @param account
     */
    private void accountChanged(ZooomrAccount account) {
        resetUI();
        initUI();
        account.save();
        this.layout();
        parent.accountChanged();
    }

    public void accountChanged() {

    }

    private void disposed(DisposeEvent event) {
        if (api.isCurrentAccountAuthenticated()) {
            accountType.dispose();
            accountTypeLabel.dispose();
            downloadLimit.dispose();
            downloadLimitLabel.dispose();
            accounts.dispose();
            accountsLabel.dispose();
        }
        authorize.dispose();
        authorizeLabel.dispose();
        addAnotherAccount.dispose();
        addAnotherAccountLabel.dispose();
    }

}